Advertisement

Inheritance in Python | Types of Inheritance | Advantage & Disadvantage of Inheritance

Inheritance in Python

Overview

The object-oriented paradigm places a lot of emphasis/importance on inheritance. Because we can use an existing class to create a new class rather than creating it again from the start, inheritance allows the us to reuse code. With inheritance, the child class access to all the data members, functions, and properties defined in the parent class of that class. A child class may also offer its additional implementation of the parent class's functions. A child/derived class in Python can inherit from its parent/base class by simply putting its name in brackets after the derived class name.

Scope

  • In this blog, we will start by learning about basics of classes and objects in Python.
  • We will also learn what Inheritance is.
  • Then, we will discuss in detail about special functions for Inheritance in Python.
  • And finally we will jump into cons and pros of Inheritance.

Introduction

Python is one of the most used programming languages in the world currently. It supports multiple types of programming styles, from the very basic method coding to advance level object-oriented programming. Due to its ease of syntax, python has become a famous/popular choice of language for OOPs.

Inheritance is one of the basic (most used) concepts of OOPs. In this blog, we will look at this robust feature and its various types with practical examples. But before we go into deep, we must get familiar with some important coding concepts like Objects and Classes.

What is Inheritance?

Inheritance is the ability/functionality to ‘inherit’ features/properties or attributes from already written classes into newer classes we create. These features are defined data structures and the functions we can perform with them, as known as Methods. It promotes code reusability, which is considered one of the best industrial/advance coding practices as it makes the codebase modular.

In python inheritance, new class inherits from older class. The new class copies all the older class's functions and attributes without rewriting the code in the new class. This new class is called derived class, and old ones are called base class.

For example, inheritance is often used in biology to symbolize the transfer of genetic attributes from parents to their children. Similar to this, in programming we have parent/base classes and child/derived classes. In Inheritance, we derive class from other already existing class. The existing class are the parent/base class from which the attributes and methods are inherited in the child class. 

Types of Inheritance in Python

Now that we are all set with the necessary to understand how inheritance in python is carried out, let’s look at various type of inheritance.

Single Inheritance in Python

This is the simplest/easiest form of inheritance where a single child/derived class is derived from a single parent/base class. Due to its singular nature, it is also known as Simple Inheritance.


# example of single inheritance
class parent: # this is parent class
def func1(self):
print("Hello Parent")
class child(parent): # this is child class
def func2(self): # we include the parent class
print("Hello Child") # as an argument in the child
# class
# Driver Code
test = child() # object created
test.func1() # parent method called via child object
test.func2() # child method called


Output:

> Hello Parent
> Hello Child


Multiple Inheritance in Python

In multiple inheritance, a single child/derived class is inherited from two or more parent/base classes. It means the child/derived class has access to all the parent/base classes' methods and attributes.

However, if two parents/bases have the same “named” methods, the child/derived class performs the method of the first parent/base in order of reference. To better understand which class’s methods shall be executed first, we can use the Method Resolution Order function (MRO). It tells the order in which the child/derived class is interpreted to visit the other classes.

# python 3 syntax
# multiple inheritance example
class parent1: # first parent class
def func1(self):
print("Hello Parent1")
class parent2: # second parent class
def func2(self):
print("Hello Parent2")
class parent3: # third parent class
def func2(self): # the function name is same as parent2
print("Hello Parent3")
class child(parent1, parent2, parent3): # child class
def func3(self): # we include the parent classes
print("Hello Child") # as an argument comma separated
# Driver Code
test = child() # object created
test.func1() # parent1 method called via child
test.func2() # parent2 method called via child instead of parent3
test.func3() # child method called
# to find the order of classes visited by the child class, we use __mro__ on the child class
print(child.__mro__)


Output:

> Hello Parent1
> Hello Parent2
> Hello Child
>(<class '__main__.child'>, <class '__main__.parent1'>,
<class '__main__.parent2'>, <class '__main__.parent3'>,<class 'object'>)


As we can see with the help of MRO, the child/derived class first visits itself, then the first parent/base class, referenced before the second parent/base class. Similarly, it visits the second parent/base class before the third parent/base class, and that’s why it performs the second parent’s function rather than the third parent’s. Finally, it visits any objects that may have been created.

Multilevel Inheritance in Python

In this type of inheritance, we further go beyond just a parent-child relation. We also introduce grandchildren, great-grandchildren, grandparents, etc. We have known only two levels of inheritance with a superior parent class/es and a derived class/es, but here we can have multiple levels where the parent class/es itself is derived from another class/es.

class grandparent: # first level
def func1(self):
print("Hello Grandparent")
class parent(grandparent): # second level
def func2(self):
print("Hello Parent")
class child(parent): # third level
def func3(self):
print("Hello Child")
# Driver Code
test = child() # object created
test.func1() # 3rd level calls 1st level
test.func2() # 3rd level calls 2nd level
test.func3() # 3rd level calls 3rd level

Output

> Hello Grandparent
> Hello Parent
> Hello Child


Hierarchical Inheritance in Python

It is the right opposite of multiple inheritance. It means that, there are multiple derived child/derived classes from a single/base parent class.

# python 3 syntax
# hierarchical inheritance example
class parent: # parent class
def func1(self):
print("Hello Parent")
class child1(parent): # first child class
def func2(self):
print("Hello Child1")
class child2(parent): # second child class
def func3(self):
print("Hello Child2")
# Driver Code
test1 = child1() # objects created
test2 = child2()
test1.func1() # child1 calling parent method
test1.func2() # child1 calling its own method
test2.func1() # child2 calling parent method
test2.func3() # child2 calling its own method

Output

Hello Parent
> Hello Child1
> Hello Parent
> Hello Child2

Hybrid Inheritance in Python

Hybrid Inheritance is the mixture/composure of two or more different types of inheritance. Here we can have many relationships between parent/base and child/derived classes with multiple levels.

# python 3 syntax
# hybrid inheritance example
class parent1: # first parent class
def func1(self):
print("Hello Parent")
class parent2: # second parent class
def func2(self):
print("Hello Parent")
class child1(parent1): # first child class
def func3(self):
print("Hello Child1")
class child2(child1, parent2): # second child class
def func4(self):
print("Hello Child2")
# Driver Code
test1 = child1() # object created
test2 = child2()
test1.func1() # child1 calling parent1 method
test1.func3() # child1 calling its own method
test2.func1() # child2 calling parent1 method
test2.func2() # child2 calling parent2 method
test2.func3() # child2 calling child1 method
test2.func4() # child2 calling its own method

Output:

> Hello Parent1
> Hello Child1
> Hello Parent1
> Hello Parent2
> Hello Child1
> Hello Child2

This example shows us a combination of three types of python inheritance.

Parent1 -> Child1 : Single Inheritance

Parent1 -> Child1 -> Child2 : Multi – Level Inheritance

Parent1 -> Child2   <- Parent2 : Multiple Inheritance

The diagrammatic explanation of this hybrid inheritance is:

Special Functions in Python Inheritance

Python is a very versatile/flexible and user-friendly language. It provides many amazing in-built functions that make our lives easier when understanding inheritance or other concepts, especially of a complex nature.

super() function

Method overriding is an ability of any object-oriented programming language that allows a subclass or child/derived class to provide a specific implementation of a method already provided by one of its super-classes or parent/base classes. This discrepancy is caused due to same naming convention of the methods. Commonly we can see this situation when the parent’s init() is overridden by the child’s init(), and hence the child class cannot inherit attributes from the parent class.

Similarly, we can face this same problem with methods other than init but having the same naming methods across parent and child classes.

One solution is to call the parent method inside the child method.

# python 3 syntax
# solution to method overriding - 1
class parent: # parent class
def __init__(self): # __init__() of parent
self.attr1 = 50
self.attr2 = 66
class child(parent): # child class
def __init__(self): # __init__() of child
parent.__init__(self) # calling parent’s __init__()
self.attr3 = 45
test = child() # object initiated
print (test.attr1) # parent attribute called via child

Output:

> 50

Advantages of Inheritance in Python

  • Modular Codebase: Increases modularity, i.e. breaking/dividing down codebase into modules, making it easier to understand. Here, every class we define becomes a separate module that can be inherited separately by one/many classes.
  • Code Reusability: the child/derived class copies all the attributes and methods of the parent/base class into its class and use. It saves time and coding effort by not copying them, thus following modularity paradigms.
  • Less Development and Maintenance Costs: changes need to be made in the base/Parent class, all derived classes will automatically follow.
    Credit: Scaler Topics

Disadvantages of Inheritance in Python

  • Decreases the Execution Speed: it decrease the speed by loading multiple classes because they are interdependent.
  • Tightly Coupled Classes: this means that even though parent/base classes can be executed independently, child/derived classes cannot be executed without defining their parent classes.



Post a Comment

0 Comments